package com.zmn.brs.business.impl.record;

import com.alibaba.fastjson.JSONObject;
import com.site.lookup.util.StringUtils;
import com.zmn.brs.business.interfaces.record.OperateRecordBService;
import com.zmn.brs.business.interfaces.record.ThresholdBService;
import com.zmn.brs.common.constant.BrsConst;
import com.zmn.brs.common.constant.RedisKeyConst;
import com.zmn.brs.common.enums.EventEnum;
import com.zmn.brs.common.enums.SceneTypeEnum;
import com.zmn.brs.common.model.mq.OperateRecordMq;
import com.zmn.brs.common.model.mq.StaffOperateRecordMq;
import com.zmn.brs.common.util.ObjectConvertUtil;
import com.zmn.brs.drools.bean.ObjectInfo;
import com.zmn.brs.drools.bean.SafetyMonitor;
import com.zmn.brs.drools.cache.DroolsCache;
import com.zmn.brs.model.entity.event.Event;
import com.zmn.brs.model.entity.record.EventRecord;
import com.zmn.brs.model.entity.record.EventRecordQuery;
import com.zmn.brs.model.entity.robot.DingGroupRobot;
import com.zmn.brs.model.entity.threshold.Threshold;
import com.zmn.brs.model.entity.threshold.ThresholdBase;
import com.zmn.brs.model.query.record.ObjectQuery;
import com.zmn.brs.model.query.record.ObjectQueryData;
import com.zmn.brs.model.result.OperateRecordResult;
import com.zmn.brs.services.interfaces.drools.RuleDroolsService;
import com.zmn.brs.services.interfaces.event.EventService;
import com.zmn.brs.services.interfaces.record.EventRecordService;
import com.zmn.brs.services.interfaces.robot.DingGroupRobotService;
import com.zmn.brs.services.interfaces.rule.AlarmRuleService;
import com.zmn.brs.services.interfaces.threshold.ThresholdService;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.dto.KvDTO;
import com.zmn.common.dto.VtDTO;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.dto2.data.LayuiTableDO;
import com.zmn.common.utils.string.StringUtil;
import com.zmn.engineer.common.model.dro.basic.BasicInfoDRO;
import com.zmn.engineer.common.model.query.engineer.SearchQuery;
import com.zmn.engineer.dubbo.interfaces.engbaseinfo.BaseInfoListRemoteService;
import com.zmn.mcc.common.dto.dingtalk.RobotSendGroupMessage;
import com.zmn.mcc.common.dto.staff.StaffDRO;
import com.zmn.mcc.dubbo.dto.DubboConsts;
import com.zmn.mcc.dubbo.interfaces.staff.StaffListRemoteService;
import com.zmn.mcc.dubbo.interfaces.staff.dingtalk.DingTalkRemoteService;
import com.zmn.mer.common.dio.factory.FactoryPageQueryDIO;
import com.zmn.mer.common.dro.factory.FactoryBaseDRO;
import com.zmn.mer.common.dro.factory.FactoryDRO;
import com.zmn.mer.dubbo.interfaces.factory.FactoryListRemoteService;
import com.zmn.plat.common.dto.area.AreaDRO;
import com.zmn.plat.common.dto.channel.ChannelDRO;
import com.zmn.plat.dubbo.interfaces.area.BaseAreaListRemoteService;
import com.zmn.plat.dubbo.interfaces.channel.ChannelListRemoteService;
import com.zmn.sp.common.model.manage.SpServProviderDRO;
import com.zmn.sp.dubbo.interfaces.manage.SpManageListRemoteService;
import com.zmn.uuc.common.dro.user.UserDetailDRO;
import com.zmn.uuc.dubbo.interfaces.user.UserListRemoteService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Reference;
import org.kie.api.KieBase;
import org.kie.api.runtime.KieSession;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 类描述：操作记录业务服务实现
 *
 * @author xujie
 * @since 2021/03/16 10:04
 * @modifier zhangyao 2021/04/21
 */
@Slf4j
@Service
public class OperateRecordBServiceImpl implements OperateRecordBService {

    public static final String TAG = "操作记录业务服务实现";

    private static final Integer SP_PROVIDER_BY_KEYWORD_SEARCH_TYPE = 1;

    @Reference(version = com.zmn.mcc.dubbo.dto.DubboConsts.INTERFACE_VERSION, check = false)
    StaffListRemoteService staffListRemoteService;

    @Reference(version = com.zmn.plat.dubbo.utils.DubboConsts.INTERFACE_VERSION, check = false)
    BaseAreaListRemoteService areaListRemoteService;

    @Reference(version = com.zmn.engineer.dubbo.constant.DubboConsts.INTERFACE_VERSION, check = false)
    BaseInfoListRemoteService baseInfoListRemoteService;

    @Reference(version = DubboConsts.INTERFACE_VERSION, check = false)
    UserListRemoteService userListRemoteService;

    @Reference(version = com.zmn.sp.dubbo.utils.DubboConsts.INTERFACE_VERSION, check = false)
    SpManageListRemoteService spManageListRemoteService;

    @Reference(version = com.zmn.mer.dubbo.utils.DubboConsts.INTERFACE_VERSION, check = false)
    FactoryListRemoteService factoryListRemoteService;

    @Reference(version = com.zmn.plat.dubbo.utils.DubboConsts.INTERFACE_VERSION, check = false)
    ChannelListRemoteService channelListRemoteService;

    @Resource
    RedisTemplate<String, String> redisTemplate;

    @Reference(version = DubboConsts.INTERFACE_VERSION, check = false)
    DingTalkRemoteService dingTalkRemoteService;

    @Resource
    private EventService eventService;

    @Resource
    private AlarmRuleService ruleService;

    @Resource
    private ThresholdService thresholdService;

    @Resource
    private RuleDroolsService droolsService;

    @Resource
    private EventRecordService eventRecordService;

    @Resource
    private DingGroupRobotService robotService;

    @Override
    public boolean eventTriggering(StaffOperateRecordMq recordMq) {
        OperateRecordMq operateRecordMq = OperateRecordMq.builder()
                .objectId(Long.parseLong(recordMq.getStaffId()))
                .objectIp(recordMq.getStaffIp())
                .createTime(recordMq.getCreateTime())
                .event(recordMq.getEvent())
                .build();
        OperateRecordResult operateRecordResult = eventTriggering(operateRecordMq);
        return operateRecordResult.getResult();
    }

    @Override
    public OperateRecordResult eventTriggering(OperateRecordMq recordMq) {

        OperateRecordResult result = OperateRecordResult.builder().result(false).build();
        long start = System.currentTimeMillis();
        List<ThresholdBase> thresholdBaseList = getThresholdBases(recordMq);
        if (thresholdBaseList == null) {
            log.error("[{}]，安全监控，未找到阈值数据，操作内容：{}", TAG, recordMq);
            result.setResult(true);
            return result;
        }
        Integer eventCode = recordMq.getEvent().getEventCode();
        Integer objectIdentity = recordMq.getObjectIdentity();
        boolean lastResult = false;
        List<EventRecord> eventRecordList = new ArrayList<>();
        ObjectInfo objectInfo = null;
        List<ThresholdBase> triggeredhresholdBase = new ArrayList<>();
        for (ThresholdBase t : thresholdBaseList) {
            KieBase kieBase = DroolsCache.KIE_BASE_MAP.get(t.getType());
            if (Objects.isNull(kieBase)) {
                log.error("[{}]，安全监控，未找到Drools的缓存数据，类型：{}", TAG, t.getType());
                continue;
            }
            // 有状态会话，与Drools引擎交互
            KieSession ks = kieBase.newKieSession();
            SafetyMonitor safety = SafetyMonitor.builder()
                    .thresholdBase(t)
                    .recordMq(recordMq)
                    .lastResult(lastResult)
                    .result(false)
                    .operateRecordBusinessServiceImpl(this)
                    .returnRole(false)
                    .build();
            ks.insert(safety);
            ks.fireAllRules();
            lastResult = safety.getResult();
            if (safety.getEventRecord() != null) {

                // 目前这个方法只有登录、查询、导出 事件会调用，等这三个事件改成和工单系统一致后就不需要了
                eventRecordList.add(safety.getEventRecord());
                triggeredhresholdBase.add(t);
                objectInfo = safety.getObjectInfo();
            }
            // 销毁前释放资源
            ks.dispose();

            if (safety.getReturnRole()) {
                log.info("安全监控，角色不满足，操作内容：{}", recordMq);
                return result;
            }
            boolean flag = eventCode >= EventEnum.VALUE_ADDED_WORK_ORDER_PLACE_AN_ORDER.getEventCode()
                    && (objectIdentity.equals(GlobalConsts.OPERATE_USER_TYPE_MASTER) || objectIdentity.equals(GlobalConsts.OPERATE_USER_TYPE_USER)
                    || objectIdentity.equals(GlobalConsts.OPERATE_USER_TYPE_FACTORY) || objectIdentity.equals(GlobalConsts.OPERATE_USER_TYPE_SERVICEPROVIDER))
                    && lastResult;
            if (flag) {
                break;
            }
        }
        if (eventRecordList.size() > 0) {
            eventRecordMessageSend(eventRecordList, objectInfo, objectIdentity);
            eventRecordService.insertBatch(eventRecordList);
        }
        log.info("[{}]，安全监控，[总耗时：{}]", TAG, (System.currentTimeMillis() - start));
        result.setTriggerThresholdBases(triggeredhresholdBase);
        result.setResult(eventRecordList.size() <= 0);
        return result;
    }

    /**
     * 触发监控
     *
     * @param safety 安全监控
     * @author xujie
     * @since 2021/03/17
     * @modifier zhangyao 2021/05/11 EventRecord增加字段
     */
    public void triggerMonitor(SafetyMonitor safety) {

        if (!safety.getResult()) {
            return;
        }
        Integer plat = safety.getRecordMq().getPlat() != null ? safety.getRecordMq().getPlat().getCode() : null;
        Long objectId = safety.getRecordMq().getObjectId();
        Integer eventCode = safety.getRecordMq().getEvent().getEventCode();
        Integer thresholdId = safety.getThresholdBase().getThresholdId();
        Integer objectIdentityAttribute = safety.getThresholdBase().getObjectIdentityAttribute();
        Integer objectIdentity = safety.getRecordMq().getObjectIdentity();
        if (eventCode < EventEnum.VALUE_ADDED_WORK_ORDER_PLACE_AN_ORDER.getEventCode()) {
            // 对于场景为 登陆、查询、导出 的操作记录，设置对象身份为员工，对象身份属性为ID
            objectIdentityAttribute = objectIdentityAttribute == null ? BrsConst.OBJECT_IDENTITY_ATTRIBUTE_ID : objectIdentityAttribute;
            objectIdentity = objectIdentity == null ? GlobalConsts.OPERATE_USER_TYPE_STAFF : objectIdentity;
        }
        JSONObject expandJson = new JSONObject();
        expandJson.put("gate", safety.getRecordMq().getGate());
        expandJson.put("plat", plat);
        expandJson.put("channelId", safety.getRecordMq().getChannelId());
        expandJson.put("objectIp", safety.getRecordMq().getObjectIp());
        expandJson.put("objectIdentity", objectIdentity);
        expandJson.put("objectIdentityAttribute", objectIdentityAttribute);
        EventRecord record = EventRecord.builder()
                .objectId(objectId)
                .eventCode(eventCode)
                .thresholdId(thresholdId)
                .messageSend(GlobalConsts.NO)
                .createTime(safety.getRecordMq().getCreateTime())
                .expand(expandJson.toJSONString())
                .build();
        safety.setEventRecord(record);
    }

    /**
     * 获取员工工作城市
     *
     * @param objectId 员工ID
     * @return 城市名
     * @author xujie
     * @since 2021/03/17
     */
    public String getStaffWorkPlaceCityName(Integer objectId) {

        ResponseDTO<Integer> result = staffListRemoteService.getWorkPlaceCity(objectId);
        Integer workPlaceCity = result.getData();
        if (workPlaceCity == null) {
            log.error("[{}]，获取员工工作城市，城市ID为空，员工ID：{}", TAG, objectId);
            return null;
        }
        ResponseDTO<AreaDRO> areaResponse = areaListRemoteService.getById(workPlaceCity);
        AreaDRO area = areaResponse.getData();
        if (area == null) {
            log.error("[{}]，获取员工工作城市，城市名为空，城市ID：{}，员工ID：{}", TAG, workPlaceCity, objectId);
            return null;
        }
        return area.getName();
    }

    /**
     * 对象频次统计
     *
     *
     * @param gate 下单入口，小类
     * @param objectIdentityAttribute 对象身份属性
     * @param objectIdentityAttributeValue 对象身份属性值
     * @param eventCode     事件编码
     * @param thresholdId 阀值id
     * @param minute      分钟
     * @author xujie
     * @since 2021/03/18
     * @modifier zhangyao 2021/04/22 修改参数Integer staffId为Long objectId
     */
    public Integer frequencyStatistics(Integer gate, Integer objectIdentityAttribute,
                                       String objectIdentityAttributeValue, Integer eventCode,
                                       Integer thresholdId, Integer minute) {

        Assert.notNull(objectIdentityAttribute, "对象身份属性不能为空");
        Assert.notNull(objectIdentityAttributeValue, "对象身份属性值不能为空");
        Assert.notNull(eventCode, "事件编码不能为空");
        Assert.notNull(thresholdId, "阀值id不能为空");
        Assert.notNull(minute, "分钟不能为空");
        String key = RedisKeyConst.getFrequencyStatistics(gate, objectIdentityAttribute, objectIdentityAttributeValue, eventCode, thresholdId);
        String value = redisTemplate.opsForValue().get(key);
        List<Long> frequencyList;
        if (StringUtil.isNotBlank(value)) {
            frequencyList = JSONObject.parseArray(value, Long.class);
            // 超时删除
            frequencyList.removeIf(frequencyTime -> System.currentTimeMillis() > frequencyTime + minute * 60 * 1000);
        } else {
            frequencyList = new ArrayList<>();
        }
        frequencyList.add(System.currentTimeMillis());
        value = JSONObject.toJSONString(frequencyList);
        redisTemplate.opsForValue().set(key, value, minute, TimeUnit.MINUTES);
        return frequencyList.size();
    }

    public void deleteFrequencyStatistics(Integer gate, Integer objectIdentityAttribute,
                                          String objectIdentityAttributeValue, Integer eventCode,
                                          Integer thresholdId, Integer minute) {

        Assert.notNull(objectIdentityAttribute, "对象身份属性不能为空");
        Assert.notNull(objectIdentityAttributeValue, "对象身份属性值不能为空");
        Assert.notNull(eventCode, "事件编码不能为空");
        Assert.notNull(thresholdId, "阀值id不能为空");
        Assert.notNull(minute, "分钟不能为空");
        String key = RedisKeyConst.getFrequencyStatistics(gate, objectIdentityAttribute, objectIdentityAttributeValue, eventCode, thresholdId);
        String value = redisTemplate.opsForValue().get(key);
        List<Long> frequencyList;
        if (StringUtil.isBlank(value)) {
            return;
        }
        frequencyList = JSONObject.parseArray(value, Long.class);
        // 移除最新的一次计数
        frequencyList.remove(frequencyList.size() - 1);
        value = JSONObject.toJSONString(frequencyList);
        redisTemplate.opsForValue().set(key, value, minute, TimeUnit.MINUTES);
    }

    /**
     * 事件触发记录消息发送
     *
     * @param eventRecordList 事件触发记录列表
     * @param objectInfo 对象信息
     * @param objectIdentity 对象身份
     * @author xujie
     * @since 2021/03/18
     * @modifier zhangyao 2021/04/21 增加参数objectIdentity
     */
    private void eventRecordMessageSend(List<EventRecord> eventRecordList, ObjectInfo objectInfo, Integer objectIdentity) {

        EventRecord lastRecord = eventRecordList.get(eventRecordList.size()-1);
        JSONObject lastRecordExpand = org.apache.commons.lang3.StringUtils.isEmpty(lastRecord.getExpand()) ? new JSONObject() : JSONObject.parseObject(lastRecord.getExpand());
        Integer objectIdentityAttribute = ObjectConvertUtil.toInteger(lastRecordExpand.get("objectIdentityAttribute"), GlobalConsts.NONE);
        String objectIp = ObjectConvertUtil.toString(lastRecordExpand.get("objectIp"), "");
        String objectMobile = ObjectConvertUtil.toString(lastRecordExpand.get("objectMobile"), "");
        Long objectId = lastRecord.getObjectId();
        if (objectInfo == null) {
            if (objectId != null && GlobalConsts.NONE != objectId && GlobalConsts.NO != objectId) {
                objectInfo = getObjectInfo(lastRecord.getEventCode(), objectId, objectIdentity);
            } else {
                objectInfo = ObjectInfo.builder().objectIdentity(objectIdentity).build();
            }
        }
        // 查询渠道信息
        ResponseDTO<ChannelDRO> channelResponse = channelListRemoteService.getByChannelId(lastRecord.getChannelId());
        ChannelDRO channelDRO = channelResponse.getData();
        if (channelDRO == null) {
            log.info("[{}]，查询渠道信息为空，渠道ID：{}，对象id：{}", TAG, lastRecord.getChannelId(), objectId);
        }
        StringBuilder triggerRuleName = new StringBuilder("触发安全规则：【");
        for (EventRecord e : eventRecordList) {
            e.setSceneType(SceneTypeEnum.SENSITIVE.getTypeId());
            Threshold threshold = thresholdService.findById(e.getThresholdId());
            if (threshold == null) {
                continue;
            }
            triggerRuleName.append(ThresholdBService.thresholdValueTranslate(threshold.getThresholdName(), threshold.getExpression(), threshold.getThresholdValue()));
            triggerRuleName.append("-");
            e.setObjectName(objectInfo.getObjectName());
            e.setRealName(objectInfo.getRealName());
            e.setMonitorScene(ThresholdBService.thresholdValueTranslate(threshold.getThresholdName(), threshold.getExpression(), threshold.getThresholdValue()));
        }
        Integer eventCode = lastRecord.getEventCode();
        Event event = eventService.findByEventCode(eventCode);
        if (event == null) {
            return;
        }
        String ruleName = "【" + event.getEventName() + "】";
        if (StringUtils.isNotEmpty(event.getSceneName())) {
            ruleName = "【" + event.getSceneName() + "】" + ruleName;
        }
        triggerRuleName.replace(triggerRuleName.length() - 1, triggerRuleName.length(), "");
        triggerRuleName.append("】");
        Map<String, Object> expand = new HashMap<>(2);
        expand.put("objectIdentityAttribute", objectIdentityAttribute);
        EventRecordQuery query = EventRecordQuery.builder()
                .objectId(objectId)
                .messageSend(GlobalConsts.YES)
                .expand(expand)
                .robotId(event.getRobotId())
                .build();
        if (objectInfo.getObjectId() == null) {
            if (objectIdentityAttribute.equals(BrsConst.OBJECT_IDENTITY_ATTRIBUTE_MOBILE)) {
                expand.put("objectMobile", objectMobile);
            } else if (objectIdentityAttribute.equals(BrsConst.OBJECT_IDENTITY_ATTRIBUTE_IP)) {
                expand.put("objectIp", objectIp);
            }
        }
        query.setPageIndex(1);
        query.setPageSize(1);
        query.setSceneType(SceneTypeEnum.SENSITIVE.getTypeId());
        List<EventRecord> eventRecords = eventRecordService.listPageByQuery(query);
        int time = 30 * 60 * 1000;
        // 最新发送的一条在三十分钟外，需要发送
        if (eventRecords.size() == 0 || (eventRecords.get(0).getCreateTime().getTime() + time) < System.currentTimeMillis()) {
            DingGroupRobot dingGroupRobot = robotService.findById(event.getRobotId());
            if (dingGroupRobot == null) {
                log.error("[{}]，事件触发，发送消息到钉钉群失败，查询钉钉群机器人为空，事件编码：{}，对象id：{}", TAG, eventCode, objectId);
                return;
            }
            String showObjectName = lastRecord.getObjectName();
            if (objectIdentityAttribute != null) {
                showObjectName = objectIdentityAttribute.equals(BrsConst.OBJECT_IDENTITY_ATTRIBUTE_ID) ? "ID：" + lastRecord.getObjectId().toString()
                        : objectIdentityAttribute.equals(BrsConst.OBJECT_IDENTITY_ATTRIBUTE_MOBILE) ? "手机号：" + objectMobile
                        : objectIdentityAttribute.equals(BrsConst.OBJECT_IDENTITY_ATTRIBUTE_IP) ? "IP：" + objectIp : "";
            }
            StringBuilder content = new StringBuilder();
            if (objectInfo.getObjectIdentity().equals(GlobalConsts.OPERATE_USER_TYPE_MASTER)) {
                showObjectName = eventCode < EventEnum.VALUE_ADDED_WORK_ORDER_PLACE_AN_ORDER.getEventCode() ? ("工程师ID：" + lastRecord.getObjectName()) : showObjectName;
                content.append("【滴】工程师：" + lastRecord.getRealName() + "（" + showObjectName + "），");
            } else if (objectInfo.getObjectIdentity().equals(GlobalConsts.OPERATE_USER_TYPE_STAFF)) {
                showObjectName = "工号：" + lastRecord.getObjectName();
                content.append("【滴】员工：" + lastRecord.getRealName() + "（" + showObjectName + "），");
            } else if (objectInfo.getObjectIdentity().equals(GlobalConsts.OPERATE_USER_TYPE_USER)) {
                if (objectInfo.getObjectId() == null) {
                    content.append("【滴】用户" + showObjectName + "，");
                } else {
                    content.append("【滴】用户：" + lastRecord.getRealName() + "（" + showObjectName + "），");
                }
            } else if (objectInfo.getObjectIdentity().equals(GlobalConsts.OPERATE_USER_TYPE_FACTORY)) {
                content.append("【滴】厂商：" + lastRecord.getRealName() + "（" + showObjectName + "），");
            } else if (objectInfo.getObjectIdentity().equals(GlobalConsts.OPERATE_USER_TYPE_SERVICEPROVIDER)) {
                content.append("【滴】服务商：" + lastRecord.getRealName() + "（" + showObjectName + "），");
            }
            content.append(triggerRuleName.toString() + "：" + ruleName + "，请注意  ");
            RobotSendGroupMessage message = RobotSendGroupMessage.builder()
                    .accessToken(dingGroupRobot.getAccessToken())
                    .secret(dingGroupRobot.getSecret())
                    .content(content.toString())
                    .build();
            try {
                ResponseDTO<Boolean> sendResponse = dingTalkRemoteService.sendMessageToGroupByRobot(message);
                if (sendResponse.getData()) {
                    lastRecord.setMessageSend(GlobalConsts.YES);
                } else {
                    log.error("[{}]，事件触发，发送消息到钉钉群失败，事件编码：{}，员工id：{}, 文本信息：{}", TAG, lastRecord.getEventCode(), objectId, sendResponse.getMessage());
                }
            } catch (Exception e) {
                log.error("[{}]，事件触发，发送消息到钉钉群异常，事件编码：{}，员工id：{}, error：{}", TAG, lastRecord.getEventCode(), objectId, e.getMessage());
            }
        }
    }

    /**
     * 获取对象信息
     *
     * @param eventCode 事件编码
     * @param objectId 对象id
     * @param objectIdentity 对象身份
     * @return StaffInfo
     * @author xujie
     * @since 2021/03/18
     * @modifier zhangyao 2021/04/21 增加参数objectIdentity，增加查询用户、厂商、服务商的逻辑
     */
    public ObjectInfo getObjectInfo(Integer eventCode, Long objectId, Integer objectIdentity) {

        ObjectInfo info = new ObjectInfo(objectId, "");
        EventEnum eventEnum = EventEnum.getEventEnum(eventCode);
        if (eventEnum == null) {
            return info;
        }
        if (eventCode < EventEnum.VALUE_ADDED_WORK_ORDER_PLACE_AN_ORDER.getEventCode()) {
            // 事件场景为：登陆 导出 查询
            if (EventEnum.ENGINEER_APP_LOGIN.getEventCode().equals(eventEnum.getEventCode())) {
                objectIdentity = GlobalConsts.OPERATE_USER_TYPE_MASTER;
            } else {
                objectIdentity = GlobalConsts.OPERATE_USER_TYPE_STAFF;
            }
        }
        info.setObjectIdentity(objectIdentity);
        if (objectIdentity.equals(GlobalConsts.OPERATE_USER_TYPE_STAFF)) {
            ResponseDTO<StaffDRO> response = staffListRemoteService.getStaff(objectId.intValue());
            StaffDRO staff = response.getData();
            if (staff == null) {
                log.info("[{}]，查询员工信息为空，事件编码：{}，员工id：{}", TAG, eventCode, objectId);
                staff = new StaffDRO();
                staff.setStaffName("");
            }
            info.setRealName(staff.getRealName());
            info.setObjectName(staff.getStaffName());
        } else if (objectIdentity.equals(GlobalConsts.OPERATE_USER_TYPE_MASTER)) {
            ResponseDTO<BasicInfoDRO> response = baseInfoListRemoteService.getBasicInfo(objectId.intValue());
            BasicInfoDRO basicInfo = response.getData();
            if (basicInfo == null) {
                log.error("[{}]，查询工程师为空，工程师ID：{}", TAG, objectId);
                basicInfo = new BasicInfoDRO();
            }
            info.setRealName(basicInfo.getRealname());
            info.setObjectName(objectId + "");
            info.setCityName(basicInfo.getCityName());
            info.setPlat(basicInfo.getPlat());
        } else if (objectIdentity.equals(GlobalConsts.OPERATE_USER_TYPE_USER)) {
            ResponseDTO<UserDetailDRO> response = userListRemoteService.getUserDetailById(objectId, false);
            UserDetailDRO userDetail = response.getData();
            if (userDetail == null) {
                log.error("[{}]，查询用户为空，用户ID：{}", TAG, objectId);
                userDetail = new UserDetailDRO();
                userDetail.setUserName("");
            }
            info.setRealName(userDetail.getNickName());
            info.setObjectName(userDetail.getUserName());
            info.setPlat(userDetail.getPlat());
        } else if (objectIdentity.equals(GlobalConsts.OPERATE_USER_TYPE_FACTORY)) {
            ResponseDTO<FactoryDRO> response = factoryListRemoteService.getFactoryById(objectId.intValue());
            FactoryDRO factory = response.getData();
            if (factory == null) {
                log.error("[{}]，查询厂商为空，厂商ID：{}", TAG, objectId);
                factory = new FactoryDRO();
                factory.setUsername("");
            }
            info.setRealName(factory.getCompanyName());
            info.setObjectName(factory.getUsername());
        } else if (objectIdentity.equals(GlobalConsts.OPERATE_USER_TYPE_SERVICEPROVIDER)) {
            ResponseDTO<SpServProviderDRO> response = spManageListRemoteService.getServProviderById(objectId.intValue());
            SpServProviderDRO spServProvider = response.getData();
            if (spServProvider == null) {
                log.error("[{}]，查询服务商为空，服务商ID：{}", TAG, objectId);
                spServProvider = new SpServProviderDRO();
                spServProvider.setUsername("");
            }
            info.setRealName(spServProvider.getName());
            info.setObjectName(spServProvider.getUsername());
            info.setPlat(spServProvider.getPlat());
        }
        return info;
    }

    private List<ThresholdBase> getThresholdBases(OperateRecordMq recordMq) {

        EventEnum eventEnum = recordMq.getEvent();
        if (eventEnum == null) {
            log.error("[{}]，事件触发，事件编码为空：{}", TAG, recordMq);
            return null;
        }
        Integer eventCode = eventEnum.getEventCode();
        Integer objectIdentity = recordMq.getObjectIdentity();
        Event event = eventService.findByEventCode(eventCode);
        if (event == null) {
            log.error("[{}]，事件触发，查询事件为空：{}", TAG, recordMq);
            return null;
        }
        if (GlobalConsts.NO == event.getStatus()) {
            log.info("[{}]，事件触发，事件已停用，事件编码：{}，参数：{}", TAG, eventCode, recordMq);
            return null;
        }
        List<Integer> ruleIdList = null;
        if (EventEnum.VALUE_ADDED_WORK_ORDER_PLACE_AN_ORDER.getEventCode() > eventCode) {
            ruleIdList = ruleService.findRuleIdByEventCode(eventCode);
            if (ruleIdList.size() == 0) {
                log.info("[{}]，事件触发，事件规则为空，事件编码：{}，参数：{}", TAG, eventCode, recordMq);
                return null;
            }
        }else{
            ruleIdList = ruleService.findRuleIdByEventCodeAndObjectIdentity(eventCode, objectIdentity);
            if (ruleIdList.size() == 0) {
                log.info("[{}]，事件触发，事件规则为空，事件编码：{}，对象身份：{}，参数：{}", TAG, eventCode, objectIdentity, recordMq);
                return null;
            }
        }
        List<ThresholdBase> thresholdBaseList = thresholdService.listByRuleIdList(ruleIdList);
        if (thresholdBaseList.size() == 0) {
            log.info("[{}]，事件触发，阀值数据为空，事件编码：{}，参数：{}", TAG, eventCode, recordMq);
            return null;
        }
        return thresholdBaseList;
    }

    @Override
    public List<VtDTO> listObjectByQuery(ObjectQuery query) {
        ObjectQueryData queryData;
        if (query == null || query.getBody() == null) {
            queryData = ObjectQueryData.builder()
                    .objectIdentity(GlobalConsts.OPERATE_USER_TYPE_STAFF)
                    .build();
        } else {
            queryData = query.getBody();
        }
        Integer objectIdentity = queryData.getObjectIdentity();
        String keyword = queryData.getKeyword();
        if (objectIdentity == null) {
            objectIdentity = GlobalConsts.OPERATE_USER_TYPE_STAFF;
        }
        List<VtDTO> list = null;
        if (objectIdentity.equals(GlobalConsts.OPERATE_USER_TYPE_STAFF)) {
            // 员工
            List<StaffDRO> data = Optional.ofNullable(staffListRemoteService.listStaffByKeyword(keyword, GlobalConsts.YES).getData()).orElse(new ArrayList<>());
            list = data.stream().map(item -> new VtDTO(item.getStaffId(), item.getRealName() + "<" + item.getMobile() + ">" + transferStaffStatus(item.getStaffStatus())))
                    .collect(Collectors.toList());
        } else if (objectIdentity.equals(GlobalConsts.OPERATE_USER_TYPE_MASTER)) {
            // 工程师
            SearchQuery searchQuery = SearchQuery.builder()
                    .keyword(keyword)
                    .build();
            list = Optional.ofNullable(baseInfoListRemoteService.searchEngineer(searchQuery).getData()).orElse(new ArrayList<>());
        } else if (objectIdentity.equals(GlobalConsts.OPERATE_USER_TYPE_FACTORY)) {
            // 厂商
            FactoryPageQueryDIO factoryPageQueryDIO = new FactoryPageQueryDIO();
            factoryPageQueryDIO.setCompanyName(keyword);
            LayuiTableDO<FactoryBaseDRO> data = Optional.ofNullable(factoryListRemoteService.listPageByQuery(factoryPageQueryDIO).getData()).orElse(new LayuiTableDO<>());
            if (data == null || data.getData() == null) {
                return list;
            }
            list = data.getData().stream().map(item -> new VtDTO(item.getFcId(), item.getFullName())).collect(Collectors.toList());
        } else if (objectIdentity.equals(GlobalConsts.OPERATE_USER_TYPE_SERVICEPROVIDER)) {
            // 服务商
            // searchType写死为1，没有实际意义
            List<KvDTO<Integer, String>> data = Optional.ofNullable(spManageListRemoteService.findSpProviderByKeyword(SP_PROVIDER_BY_KEYWORD_SEARCH_TYPE, keyword).getData()).orElse(new ArrayList<>());
            list = data.stream().map(item -> new VtDTO(item.getKey(), item.getValue())).collect(Collectors.toList());
        }
        return list;
    }

    /**
     * 转换员工状态
     * @param staffStatus 员工状态值
     * @return java.lang.String 员工状态释义
     * @throws
     * @author zhangyao
     * @since 2021/04/24 17:29
     */
    public String transferStaffStatus(Integer staffStatus) {
        staffStatus = Optional.ofNullable(staffStatus).orElse(0);
        String text = staffStatus == 1 ? "试用" : staffStatus == 2 ? "正式" : staffStatus == 3 ? "离职" : "";
        return "<" + text + ">";
    }

    @Override
    public String getObjectIdentityAttributeValue(OperateRecordMq recordMq, Integer objectIdentityAttribute) {
        Long objectId = recordMq.getObjectId();
        String objectIdentityAttributeValue = objectId.toString();
        if (objectIdentityAttribute == BrsConst.OBJECT_IDENTITY_ATTRIBUTE_MOBILE) {
            if (StringUtils.isEmpty(recordMq.getObjectMobile())) {
                return null;
            }
            objectIdentityAttributeValue = recordMq.getObjectMobile();
        } else if (objectIdentityAttribute == BrsConst.OBJECT_IDENTITY_ATTRIBUTE_IP) {
            if (StringUtils.isEmpty(recordMq.getObjectIp())) {
                return null;
            }
            objectIdentityAttributeValue = recordMq.getObjectIp();
        }
        return objectIdentityAttributeValue;
    }

}
